import { math, v3, Vec3 } from 'cc'
import { bt } from "../../bt/BehaviorTree"
import { Actor } from "../Actor"
import { EnemyController } from '../EnemyController'
import { SimpleEmitter } from "../projectile/SimpleEmitter"
import { StateDefine } from "../StateDefine"
import { BlackboardKey } from "./BlackboardKey"
// 移动至目标点
export class MoveToDest extends bt.Action {
    execute(dt: number, result: bt.ExecuteResult) {
        let actor: Actor = result.blackboard.get(BlackboardKey.Actor)
        let MoveDest: Vec3 = result.blackboard.get(BlackboardKey.MoveDest).clone()
        if (!actor || !MoveDest) {
            bt.markFail(result)
            return
        }
        // 剩余执行时间
        let dur: number = result.blackboard.get(BlackboardKey.MoveDestDuration) - dt
        result.blackboard.set(BlackboardKey.MoveDestDuration, dur)
        let dir = MoveDest.subtract(actor.node.position)
        let distance = dir.length()
        dir.normalize()
        // 执行时间结束 或者距离目标小于10 结束行为
        if (dur < 0 || distance < 10) {
            bt.markSuccess(result)
            result.blackboard.delete(BlackboardKey.MoveDest)
            actor.stateMgr.transit(StateDefine.Idle)
            return
        }
        actor.input.set(dir.x, dir.y)
        bt.markRunning(result)
        actor.stateMgr.transit(StateDefine.Run)

    }
}
// 设置移动目标
export class SetMoveDest extends bt.Action {
    execute(dt: number, result: bt.ExecuteResult) {
        bt.markSuccess(result)
        let actor = result.blackboard.get(BlackboardKey.Actor) as Actor
        let ec = actor.node.getComponent(EnemyController)
        ec.randomNextMoveDest()
    }
}


//判断技能是否在冷却
export class IsCooldown extends bt.Condition {
    emitter: SimpleEmitter = null;
    isSatisfy(result: bt.ExecuteResult): boolean {
        return this.emitter.isCoolingdown
    }
}
export class Emit extends bt.Action {
    emitter: SimpleEmitter = null
    execute(dt: number, result: bt.ExecuteResult) {
        bt.markSuccess(result)
        this.emitter.emit()
    }
}
export class StayIdle extends bt.Action {
    execute(dt: number, result: bt.ExecuteResult) {
        bt.markSuccess(result)
        let actor: Actor = result.blackboard.get(BlackboardKey.Actor)
        actor.stateMgr.transit(StateDefine.Idle)
    }
}
export class IsLowHp extends bt.Condition {
    isSatisfy(result: bt.ExecuteResult): boolean {
        let actor = result.blackboard.get(BlackboardKey.Actor) as Actor
        return actor?.hp / actor?.maxHp <= 0.5
    }
}


/**
 * @en
 * Use dash to escape
 * @zh
 * 使用突进来逃跑
 */
export class EscapeDash extends bt.Action {
    execute(dt: number, result: bt.ExecuteResult) {
        let actor: Actor = result.blackboard.get(BlackboardKey.Actor)

        // 当前在 dash 则不重进此状态
        if (actor.stateMgr.currState.id == StateDefine.Dash) {
            bt.markSuccess(result)
            result.blackboard.set(BlackboardKey.Escaped, true)
            return
        }

        // 随机找一个方向，然后使用 dash 状态来逃跑
        let dir = v3(math.randomRange(-1, 1), math.randomRange(-1, 1), 0)
        let target: Actor = result.blackboard.get(BlackboardKey.Target)
        if (target) {
            Vec3.subtract(dir, actor.node.worldPosition, target.node.worldPosition)
        }

        dir.normalize()
        actor.input.set(dir.x, dir.y)
        actor.stateMgr.transit(StateDefine.Dash)
        bt.markRunning(result)
    }
}
